package org.tof.hotel.entity;

import org.apache.log4j.Logger;
import org.tof.hotel.RoomLevel;
import org.tof.hotel.csv.CSVParser;
import org.tof.hotel.csv.CSVWriter;

import java.util.ArrayList;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

/**
 * This class corresponds to the Application form filled in by a Customer
 *
 * @author A.Timofieiev
 * @see Customer
 */
public class Application extends BaseForRoom {
    public Application(int beds, RoomLevel roomLevel, Customer customer, Date beginDate, Date endDate, Administrator administrator) {
        super(beds, roomLevel);
        setFillingDate(new Date());
        setCustomer(customer);
        setBeginDate(beginDate);
        setEndDate(endDate);
        setAdministrator(administrator);
        applications.add(this);
        logger.debug("generated object of class \"Application\"");
    }

    static Logger logger = Logger.getLogger(Application.class.getName());
    // -----fields----- //
    private Date fillingDate;
    private Date beginDate;
    private Date endDate;
    private Customer customer;
    private Administrator administrator;

    public static ArrayList<Application> applications = new ArrayList<Application>();

    // -----getters & setters----- //

    public Date getFillingDate() {
        return fillingDate;
    }

    public void setFillingDate(Date fillingDate) {
        this.fillingDate = fillingDate;
    }

    public Date getBeginDate() {
        return beginDate;
    }

    public void setBeginDate(Date beginDate) {
        this.beginDate = beginDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public Administrator getAdministrator() {
        return administrator;
    }

    public void setAdministrator(Administrator administrator) {
        this.administrator = administrator;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    // -----methods------ //

    /**
     * Returns all applications filled in by specified Customer.
     *
     * @param customer <code>Customer</code> whose applications to look for
     * @return <code>ArrayList<Application></code> if there are applications, filled by this customer; <code>null</code> otherwise
     * @see Customer
     */
    public static ArrayList<Application> byCustomer(Customer customer) {
        ArrayList<Application> list = new ArrayList<Application>();
        for (Application a : applications) {
            if (a.getCustomer() == customer) {
                list.add(a);
            }
        }
        if (!list.isEmpty()) {
            return list;
        } else {
            return null;
        }
    }
    // ----- GeneratoR ----- //
    @Override
    public void generate(int num) {
        logger.debug("generating " + num + " objects of class \"Application\"");
        Random r = new Random();
        RoomLevel[] roomLevels = RoomLevel.values();
        for(int i=1; i<=num; i++){
            new Application(r.nextInt(4),
                    roomLevels[r.nextInt(4)],
                    Customer.customers.get(r.nextInt(Customer.customers.size())),
                    new Date(), new Date(),
                    Administrator.administrators.get(r.nextInt(Administrator.administrators.size())));
        }
    }
    // ----- CSVGenerable-generator ----- //
    @Override
    public String getFieldNames() {
        return "id,beds,roomLevel,fillingDate,beginDate,endDate,customerId,administratorId";
    }
    @Override
    public ArrayList<String> getFields(){
        ArrayList<String> list = new ArrayList<String>();
        ArrayList<String> tmp = new ArrayList<String>();
        for(Application a : applications){
            tmp.clear();
            tmp.add(a.getId().toString());
            tmp.add(String.valueOf(a.getBeds()));
            tmp.add(a.getRoomLevel().toString());
            tmp.add(a.getFillingDate().toString());
            tmp.add(a.getBeginDate().toString());
            tmp.add(a.getEndDate().toString());
            tmp.add(a.getCustomer().getId().toString());
            tmp.add(a.getAdministrator().getId().toString());
            list.add(CSVWriter.getInstance().FieldsToCSVString(tmp));
        }
        return list;
    }
    //int beds, RoomLevel roomLevel, Customer customer, Date beginDate, Date endDate, Administrator administrator
    @Override
    public ArrayList<Class> createInstancesFromCsvFile(String filename) {
        CSVParser parser = new CSVParser();
        ArrayList<String[]> list = new ArrayList<String[]>(parser.parse(filename));
        ArrayList<Class> generated = new ArrayList<Class>();
        for(int i=1; i < list.size() ;i++){
            generated.add(new Application(Integer.decode(list.get(i)[1]),
                    RoomLevel.valueOf(list.get(i)[2]),
                    Customer.getById(UUID.fromString(list.get(i)[3])),
                    new Date(Date.parse(list.get(i)[4])),
                    new Date(Date.parse(list.get(i)[5])),
                    Administrator.getById(UUID.fromString(list.get(i)[6]))).getClass());
        }
        return generated;
    }

}
